package cn.jarlen.jwt.tools.crypt.device.soft;

import java.io.FileInputStream;
import java.io.IOException;
import java.security.PublicKey;

import cn.jarlen.jwt.tools.crypt.base.KeyCache;
import cn.jarlen.jwt.tools.crypt.exception.CryptOperatorException;
import cn.jarlen.jwt.tools.crypt.operator.SignOperator;

public class SoftSignOperator implements SignOperator {
    private static final SoftSignOperator softSignOperator = new SoftSignOperator();
    KeyCache keyCache = KeyCache.getInstance();

    public SoftSignOperator() {
    }

    public static SoftSignOperator getInstance() {
        return softSignOperator;
    }

    public byte[] sm2Sign(byte[] data) {
        return SoftOperatorUtil.sm2Sign(this.keyCache.getSignP12Info().getPriKey(), data);
    }

    public byte[] sm2Sign(FileInputStream fileInputStream) {
        return SoftOperatorUtil.sm2Sign(this.keyCache.getSignP12Info().getPriKey(), fileInputStream);
    }

    public boolean sm2SignVerity(FileInputStream fileInputStream, byte[] signData) {
        return SoftOperatorUtil.verifySign(this.keyCache.getSignP12Info().getPubKey(), fileInputStream, signData);
    }

    public boolean sm2SignVerity(byte[] orgData, byte[] signData) {
        return SoftOperatorUtil.verifySign(this.keyCache.getSignP12Info().getPubKey(), orgData, signData);
    }

    public boolean sm2SignVerity(String signCert, byte[] orgData, byte[] signData, boolean isUseAsn1Encode) {
        try {
            byte[] sign = this.getRealSign(signData, isUseAsn1Encode);
            PublicKey publicKey = SoftOperatorUtil.getPublicKeyByCert(signCert);
            return SoftOperatorUtil.verifySign(publicKey, orgData, sign);
        } catch (Exception var7) {
            throw new CryptOperatorException("SM2外部公钥签名验证失败");
        }
    }

    private byte[] getRealSign(byte[] signData, boolean isUseAsn1Encode) throws IOException {
        byte[] sign;
        if (isUseAsn1Encode) {
            sign = signData;
        } else {
            byte[] r = new byte[32];
            System.arraycopy(signData, 0, r, 0, 32);
            byte[] s = new byte[32];
            System.arraycopy(signData, signData.length - 32, s, 0, 32);
            sign = SoftOperatorUtil.derSignatureEncode(r, s);
        }

        return sign;
    }
}
